<?php
/**
 * 作用：微信处理模块
 * 作者: shijy@soe-soe.com
 * 日期: 2016/4/27 15:41
 * 公司: 浙江宣逸网络科技有限公司<www.soe-soe.com>
 */
namespace Common\Model;
class WeixinModel extends BaseModel{


//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////


	/**
	 * 获取微信通信用的token
	 * Author: shijy
	 * @return mixed
	 */
	public static function getAccessToken(){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		do {
					$appid 		= XIAO_APPID;					//XIAO_APPID;	//"wx681916c9f34511b4";
					$AppSecret 	= XIAO_SECRET;	//XIAO_SECRET;	//"98a6762492d80988e0e54feab038e9f9";

					$data = unserialize(S('WX_ACCESS_TOKEN'));
					$now = time();
					if ($data && $data['deadline'] > $now) {
						$dataSuccess['data'] = array(
							'appId' => $appid,
							'access_token' => $data['access_token']
						);
						return $dataSuccess;
					}

					$curlGet = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$AppSecret}";
					$ch = curl_init(); //初始化一个CURL对象
					curl_setopt($ch, CURLOPT_URL, $curlGet);
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
					curl_setopt($ch, CURLOPT_POST, 0);
					$data = curl_exec($ch);
					curl_close($ch);

					$data = json_decode($data, true);

					if (is_array($data)) {
						if ($data['errcode'] != 0) {
							$dataFailure['msg'] = $data['errmsg'];
							return $dataFailure;
						}
						$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
					} else {
						return $dataFailure;
					}
					S('WX_ACCESS_TOKEN', serialize($data));
					$dataSuccess['data'] = array(
						'appId' => $appid,
						'access_token' => $data['access_token']
					);
					return $dataSuccess;
		}while(false);
	}



	/**
	 * 获取jsapiTicket
	 * Author: shijy
	 * @param $access_token
	 * @return array
	 */
	public static function getJsApiTicket($access_token=null){
			$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
			$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');
			$data = unserialize(S('WX_JSAPI_TICKET'));

			$now = time();
			if ( false && $data && $data['deadline'] > $now) {
				$dataSuccess['data'] = array(
					'appId'=>$data['appId'],
					'ticket' => $data['ticket']
				);
				return $dataSuccess;
			}

			$appID		= 0;
			if (!$access_token){
				$ret=self::getAccessToken();
				if($ret['status']!=0){
					return $ret;
				}
				$access_token	= $ret['data']['access_token'];
				$appID			= $ret['data']['appId'];
			}


			$curlGet = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$access_token}";
			$ch = curl_init(); //初始化一个CURL对象
			curl_setopt($ch, CURLOPT_URL, $curlGet);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_POST, 0);
			$data = curl_exec($ch);
			$data = json_decode($data, true);
			curl_close($ch);


			if (is_array($data)) {
				if ($data['errcode'] != 0) {
					$dataFailure['msg'] = $data['errmsg'];
					return $dataFailure;
				}
				$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
			} else {
				return $dataFailure;
			}
			$data['appId'] = $appID;
			S('WX_JSAPI_TICKET', serialize($data));
			$dataSuccess['data'] = array(
				'appId' => $appID,
				'ticket' => $data['ticket']
			);
			return $dataSuccess;
	}

	/**
	 * 获取卡券的api_ticket
	 * Author: shijy
	 */
	public static function getCardApiTicket($access_token=null){
		$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
		$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');
		$data = unserialize(S('WX_CARDAPI_TICKET'));

		$now = time();
		if ($data && $data['deadline'] > $now) {
			$dataSuccess['data'] = array(
				'appId'=>$data['appId'],
				'ticket' => $data['ticket']
			);
			return $dataSuccess;
		}

		$appID		= 0;
		if (!$access_token){
			$ret=self::getAccessToken();
			if($ret['status']!=0){
				return $ret;
			}
			$access_token	= $ret['data']['access_token'];
			$appID			= $ret['data']['appId'];
		}

		$curlGet = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=wx_card";
		$ch = curl_init(); //初始化一个CURL对象
		curl_setopt($ch, CURLOPT_URL, $curlGet);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 0);
		$data = curl_exec($ch);
		$data = json_decode($data, true);
		curl_close($ch);


		if (is_array($data)) {
			if ($data['errcode'] != 0) {
				$dataFailure['msg'] = $data['errmsg'];
				return $dataFailure;
			}
			$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
		} else {
			return $dataFailure;
		}
		$data['appId'] = $appID;
		S('WX_CARDAPI_TICKET', serialize($data));
		$dataSuccess['data'] = array(
			'appId' => $appID,
			'ticket' => $data['ticket']
		);
		return $dataSuccess;
	}

	/**
	 * 微信分享获取signPackage
	 * Author: shijy
	 * @return array
	 */
	public static function getSignPackage(){
		$ret = self::getJsApiTicket();

		if($ret['status']!=0){
			return $ret;
		}

		$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
		$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');


		$jsapiTicket=$ret['data']['ticket'];
		$appId=$ret['data']['appId'];
		// 注意 URL 一定要动态获取，不能 hardcode.
		
		$domain=UtilsModel::getFullDomain();
		$url = "{$domain}{$_SERVER[REQUEST_URI]}";

		$timestamp = time();
		$nonceStr = self::createNonceStr();


		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";

		$signature = sha1($string);

		$signPackage = array(
			"appId"     => $appId,
			"nonceStr"  => $nonceStr,
			"timestamp" => $timestamp,
			"url"       => $url,
			"signature" => $signature,
			"rawString" => $string
		);
		
		$dataSuccess['data']=$signPackage;
		return $dataSuccess;
	}


	/**
	 * 创建随机字符串
	 * Author: shijy
	 * @param int $length
	 * @return string
	 */
	private static function createNonceStr($length = 16) {
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}
	
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////

	/**
	 * 微信专用请求函数
	 * Author: shijy
	 * @param $url
	 * @param $content
	 * @return array|mixed
	 */
	public static function send($url,$content){
		$getToken=self::getAccessToken();
		if($getToken['status']!=0){
			return $getToken;
		}


		$access_token=$getToken['data']['access_token'];
		
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');

		$url=$url.$access_token;
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
		$data = curl_exec($ch);
		$data=json_decode($data,true);
		if($data['errcode']!=0){
			$dataFailure['msg']='操作失败：'.$data['errmsg'].',errcode:'.$data['errcode'];
			return $dataFailure;
		}
		$dataSuccess['data']=$data;
		return $dataSuccess;
	}

	/**
	 * 发送微信模板消息
	 * Author: shijy
	 * @param $content
	 * @return array|mixed
	 */
	public static function sendTemplateMsg($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='; //公众号
		//$url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=';//小程序

		return self::send($url,$content);
	}

	
	
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 根据open_id群发消息
	 * Author: shijy
	 * @param $content
	 * @return array
	 */
	private static function sendMass($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=';
		return self::send($url,$content);
	}


	/**
	 * 根据openids发送卡关
	 * Author: shijy
	 * @param $OpenIDs
	 * @param $cardId
	 * @return array|mixed
	 */
	public static function sendCardByOpenID($OpenIDs,$cardId){
		$data=array(
			'touser'=>(array)$OpenIDs,
			'wxcard'=>array('card_id'=>$cardId),
			"msgtype"=>"wxcard"
		);
		return self::sendMass(json_encode($data));
	}

	/**
	 * 根据openids发送文字信息
	 * Author: shijy
	 * @param $OpenIDs
	 * @param $text
	 * @return array|mixed
	 */
	public static function sendTextByOpenID($OpenIDs,$text){
		$data=array(
			'touser'=>(array)$OpenIDs,
			'text'=>array('content'=>$text),
			"msgtype"=>"text"
		);
		return self::sendMass(json_encode($data));
	}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 发送客服消息
	 * Author: shijy
	 * @param $content
	 * @return array
	 */
	private static function sendCustom($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=';
		return self::send($url,$content);
	}


	/**
	 * 获取卡券的cardExt数组
	 * Author: shijy
	 * @param $wxCardID  微信卡券编号
	 * @param $openID
	 * @param $code
	 * @return array
	 */
	public static function getCardExt($wxCardID,$openID='',$code=''){
		$cardApiTicket=self::getCardApiTicket();
		if($cardApiTicket['status']!=0){
			return $cardApiTicket;
		}
		$card_ticket=$cardApiTicket['data']['ticket'];
		$time=time().'';
		$nonceStr=self::createNonceStr();
		$tmpArr = array($card_ticket,$time,$wxCardID,$code,$openID,$nonceStr);

		sort($tmpArr, SORT_STRING);
		$tmpStr = implode( $tmpArr );
		$signature = sha1( $tmpStr );

		$CardExt=array(
			'card_id'	=> $wxCardID,
			'code'		=> $code,
			'openid'	=> $openID,
			'timestamp'	=> $time,
			'signature'	=> $signature,
			'nonce_str' => $nonceStr,
			'outer_id'	=> 1,
		);
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataSuccess['cardExt']		= json_encode($CardExt);
		$dataSuccess['wxCardId']	= $wxCardID;
		return $dataSuccess;
	}


	/**
	 * 通过客服消息发送卡券
	 * Author: shijy
	 * @param $openID
	 * @param $cardID
	 * @param $code
	 * @return array
	 */
	public static function sendCustom_card($openID,$cardID,$code){
		$cardExtReturn=self::getCardExt($cardID,$openID,$code);
		if($cardExtReturn['status']!=0){
			return $cardExtReturn;
		}
		$cardExt=$cardExtReturn['cardExt'];

		$data=array(
			'touser'=>$openID,
			'msgtype'=>'wxcard',
			'wxcard'=>array(
				'card_id' =>$cardID,
				'card_ext'=>$cardExt
			)
		);
		return self::sendCustom(json_encode($data));
	}

	/**
	 * 通过客服消息发送普通文字
	 * Author: shijy
	 * @param $openID
	 * @param $text
	 * @return array
	 */
	public static function sendCustom_text($openID,$text){
		$data=array(
			'touser'=>$openID,
			'msgtype'=>'text',
			'text'=>array(
				'content'=>$text
			)
		);
		return self::sendCustom(json_encode($data));
	}

	/**
	 * 指查询用户信息（微信）
	 * Author: shijy
	 * @param $OpenIDs
	 * @return array|mixed
	 */
	public static function batchGetUser($OpenIDs){
		$data=array(
			'user_list'=>array()
		);
		foreach($OpenIDs as $one){
			$data['user_list'][]=array('openid'=>$one,'lang'=>'zh-CN');
		}
		$url='https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=';
		return self::send($url,json_encode($data));
	}

	//微信退款
	public static function refund($orderInfo){
		$dataSuccess = array('status'=>0,'msg'=>'成功');
		//加载微信类
		require_once WEB_ROOT."/Lib/wxpay/lib/WxPay.Api.php";
		$input = new \WxPayRefund();
		$input->SetOut_refund_no($orderInfo['outRefundNo']);
		$input->SetOp_user_id(\WxPayConfig::MCHID);
		$input->SetOut_trade_no($orderInfo['outTradeNo']);
		$input->SetTotal_fee( intval($orderInfo['total']) );//总金额
		$input->SetRefund_fee(intval($orderInfo['refund']) );//退款金额

		$order = \WxPayApi::refund($input);

		if(strcasecmp($order['return_code'],'SUCCESS')!=0){
			$dataFailure = array('status'=>1,'msg'=>$order['return_msg']);
			return $dataFailure;
		}elseif(strcasecmp($order['result_code'],'SUCCESS')!=0){
			$dataFailure = array('status'=>1,'msg'=>$order['err_code_des']);
			return $dataFailure;
		}
		$dataSuccess['data'] = $order;

		return $dataSuccess;
	}



	public static function downloadimageformweixin($url)
	{

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_URL, $url);
		ob_start();
		curl_exec($ch);
		$return_content = ob_get_contents();
		ob_end_clean();

		$return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

		return $return_content;
	}

	/**
	 * 获取小程序码
	 * @param $path
	 * @return array|mixed
	 */
	public static function getwxacode($id){
		$data=array(
			'scene'=>$id,
			'page'=>'pages/suren/begin',
			'width'=>200,
			'is_hyaline'=>true
		);
		$url="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";


		$getToken=self::getAccessToken();
		if($getToken['status']!=0){
			return $getToken;
		}
		$access_token=$getToken['data']['access_token'];

		$url=$url.$access_token;
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
		$data=curl_exec($ch);
		curl_close($ch);

		$ret=UtilsModel::saveImageByBlob($data);
		if ($ret==''){
			return array('status'=>1,'msg'=>'小程序码生成失败');
		}
		return array('status'=>0,'url'=>$ret);
	}
}